package com.share.order.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.share.common.core.domain.R;
import com.share.common.core.exception.ServiceException;
import com.share.common.core.utils.StringUtils;
import com.share.common.core.utils.bean.BeanUtils;
import com.share.common.security.utils.SecurityUtils;
import com.share.order.api.domain.EndOrderVo;
import com.share.order.api.domain.OrderBill;
import com.share.order.api.domain.OrderInfo;
import com.share.order.api.domain.SubmitOrderVo;
import com.share.order.mapper.OrderBillMapper;
import com.share.order.mapper.OrderInfoMapper;
import com.share.order.service.IOrderInfoService;
import com.share.rules.api.RemoteFeeRuleService;
import com.share.rules.api.domain.FeeRule;
import com.share.rules.api.domain.FeeRuleRequestForm;
import com.share.rules.api.domain.FeeRuleResponseVo;
import com.share.user.api.RemoteUserInfoService;
import com.share.user.api.domain.UserInfo;
import com.share.user.api.domain.UserInfoVo;
import org.joda.time.DateTime;
import org.joda.time.Minutes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * @return 13141
 * 2025/10/17
 * 15:56
 */
@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements IOrderInfoService
{
    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private RemoteFeeRuleService remoteFeeRuleService;

    @Autowired
    private RemoteUserInfoService remoteUserInfoService;

    @Autowired
    private OrderBillMapper orderBillMapper;


    @Override
    public OrderInfo getNoFinishOrder(Long userId) {
        // 查询用户是否有使用中与未支付订单
        return orderInfoMapper.selectOne(new LambdaQueryWrapper<OrderInfo>()
            .eq(OrderInfo::getUserId, userId)
            .in(OrderInfo::getStatus, Arrays.asList("0", "1"))// 订单状态：0:充电中 1：未支付 2：已支付
            .orderByDesc(OrderInfo::getId)
            .last("limit 1")
        );
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long saveOrder(SubmitOrderVo orderForm) {
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setUserId(orderForm.getUserId());
        orderInfo.setOrderNo(RandomUtil.randomString(8));
        orderInfo.setPowerBankNo(orderForm.getPowerBankNo());
        orderInfo.setStartTime(new Date());
        orderInfo.setStartStationId(orderForm.getStartStationId());
        orderInfo.setStartStationName(orderForm.getStartStationName());
        orderInfo.setStartCabinetNo(orderForm.getStartCabinetNo());
        // 费用规则
        FeeRule feeRule = remoteFeeRuleService.getFeeRule(orderForm.getFeeRuleId()).getData();
        orderInfo.setFeeRuleId(orderForm.getFeeRuleId());
        orderInfo.setFeeRule(feeRule.getDescription());
        orderInfo.setStatus("0");
        orderInfo.setCreateTime(new Date());
        orderInfo.setCreateBy(SecurityUtils.getUsername());
        //用户昵称
        UserInfo userInfo =  remoteUserInfoService.getInfo(orderInfo.getUserId()).getData();
        orderInfo.setNickname(userInfo.getNickname());

        orderInfoMapper.insert(orderInfo);
        return orderInfo.getId();
    }

    // 结束订单
    @Override
    public void endOrder(EndOrderVo endOrderVo) {
        // 获取充电中的订单，如果存在，则结束订单； 如果不存在，则返回（初始化插入，无订单）
        OrderInfo orderInfo = orderInfoMapper.selectOne(new LambdaQueryWrapper<OrderInfo>()
            .eq(OrderInfo::getPowerBankNo, endOrderVo.getPowerBankNo())
            .eq(OrderInfo::getStatus, "0") //订单状态：0:充电中
            .orderByDesc(OrderInfo::getCreateTime)
            .last("limit 1")
        );
        // 判断
        if (orderInfo == null) { // 如果不存在订单，直接返回
            return;
        }

        // 2.设置订单相关数据，进行更新
        orderInfo.setEndTime(endOrderVo.getEndTime());
        orderInfo.setEndStationId(endOrderVo.getEndStationId());
        orderInfo.setEndStationName(endOrderVo.getEndStationName());
        orderInfo.setEndCabinetNo(endOrderVo.getEndCabinetNo());
        // 包含充电时长，以分钟为单位
        Date startTime = orderInfo.getStartTime();
        Date endTime = orderInfo.getEndTime();
        int minutes = Minutes.minutesBetween(new DateTime(startTime),
            new DateTime(endTime)).getMinutes();
        orderInfo.setDuration(minutes);

        // 远程调用：规则引擎进行费用计算
        // 封装参数
        FeeRuleRequestForm feeRuleRequestForm = new FeeRuleRequestForm();
        feeRuleRequestForm.setDuration(minutes);
        feeRuleRequestForm.setFeeRuleId(orderInfo.getFeeRuleId());
        // 远程调用
        R<FeeRuleResponseVo> feeRuleResponseVoR = remoteFeeRuleService.calculateOrderFee(feeRuleRequestForm);
        FeeRuleResponseVo feeRuleResponseVo = feeRuleResponseVoR.getData();

        // 设置费用
        orderInfo.setTotalAmount(feeRuleResponseVo.getTotalAmount());
        orderInfo.setDeductAmount(new BigDecimal(0));
        orderInfo.setRealAmount(feeRuleResponseVo.getTotalAmount());

        if (orderInfo.getRealAmount().subtract(new BigDecimal(0)).doubleValue() == 0) {
            orderInfo.setStatus("2");
        } else {
            orderInfo.setStatus("1");
        }
        baseMapper.updateById(orderInfo);

        // 3.插入免费账单的数据
        OrderBill freeOrderBill = new OrderBill();
        freeOrderBill.setOrderId(orderInfo.getId());
        freeOrderBill.setBillItem(feeRuleResponseVo.getFreeDescription());
        freeOrderBill.setBillAmount(new BigDecimal(0));
        orderBillMapper.insert(freeOrderBill);

        // 4.插入收费账单数据（超过免费时间账单数据）
        BigDecimal exceedPrice = feeRuleResponseVo.getExceedPrice();
        if (exceedPrice.doubleValue() > 0) {
            OrderBill exceedOrderBill = new OrderBill();
            exceedOrderBill.setOrderId(orderInfo.getId());
            exceedOrderBill.setBillItem(feeRuleResponseVo.getExceedDescription());
            exceedOrderBill.setBillAmount(feeRuleResponseVo.getExceedPrice());
            orderBillMapper.insert(exceedOrderBill);
        }
    }

    @Override
    public List<OrderInfo> selectUserOrderInfoList(Long userId) {
        List<OrderInfo> orderInfoList = orderInfoMapper.selectList(new LambdaQueryWrapper<OrderInfo>()
            .eq(OrderInfo::getUserId, userId)
            .orderByDesc(OrderInfo::getId)
        );
        if (!CollectionUtils.isEmpty(orderInfoList)) {
            for (OrderInfo orderInfo : orderInfoList) {
                //充电中实时计算使用时间与金额
                if ("0".equals(orderInfo.getStatus())) {
                    //充电中实时计算使用时间
                    int duration = Minutes.minutesBetween(new DateTime(orderInfo.getStartTime()), new DateTime()).getMinutes();
                    if (duration > 0) {
                        orderInfo.setDuration(duration);

                        // 费用计算
                        FeeRuleRequestForm feeRuleRequestForm = new FeeRuleRequestForm();
                        feeRuleRequestForm.setDuration(duration);
                        feeRuleRequestForm.setFeeRuleId(orderInfo.getFeeRuleId());
                        R<FeeRuleResponseVo> feeRuleResponseVoResult = remoteFeeRuleService.calculateOrderFee(feeRuleRequestForm);
                        if (R.FAIL == feeRuleResponseVoResult.getCode()) {
                            throw new ServiceException(feeRuleResponseVoResult.getMsg());
                        }
                        FeeRuleResponseVo feeRuleResponseVo = feeRuleResponseVoResult.getData();

                        // 设置订单金额
                        orderInfo.setTotalAmount(feeRuleResponseVo.getTotalAmount());
                        orderInfo.setDeductAmount(new BigDecimal(0));
                        orderInfo.setRealAmount(feeRuleResponseVo.getTotalAmount());
                    } else {
                        orderInfo.setDuration(0);
                        orderInfo.setTotalAmount(new BigDecimal(0));
                        orderInfo.setDeductAmount(new BigDecimal(0));
                        orderInfo.setRealAmount(new BigDecimal(0));
                    }

                }
            }
        }
        return orderInfoList;
    }

    @Override
    public OrderInfo selectOrderInfoById(Long id) {
        OrderInfo orderInfo = orderInfoMapper.selectById(id);

        // 添加空值检查
        if (orderInfo == null) {
            // 可以根据业务需求选择：
            // 1. 返回null
            // return null;

            // 2. 抛出业务异常
            throw new ServiceException("订单不存在，订单ID：" + id);

            // 3. 返回空对象（不推荐）
            // return new OrderInfo();
        }


        //充电中实时计算使用时间与金额
        if ("0".equals(orderInfo.getStatus())) {
            //充电中实时计算使用时间
            int duration = Minutes.minutesBetween(new DateTime(orderInfo.getStartTime()), new DateTime()).getMinutes();
            if (duration > 0) {
                orderInfo.setDuration(duration);

                // 费用计算
                FeeRuleRequestForm feeRuleRequestForm = new FeeRuleRequestForm();
                feeRuleRequestForm.setDuration(duration);
                feeRuleRequestForm.setFeeRuleId(orderInfo.getFeeRuleId());
                R<FeeRuleResponseVo> feeRuleResponseVoResult = remoteFeeRuleService.calculateOrderFee(feeRuleRequestForm);
                if (R.FAIL == feeRuleResponseVoResult.getCode()) {
                    throw new ServiceException(feeRuleResponseVoResult.getMsg());
                }
                FeeRuleResponseVo feeRuleResponseVo = feeRuleResponseVoResult.getData();

                // 设置订单金额
                orderInfo.setTotalAmount(feeRuleResponseVo.getTotalAmount());
                orderInfo.setDeductAmount(new BigDecimal(0));
                orderInfo.setRealAmount(feeRuleResponseVo.getTotalAmount());
            } else {
                orderInfo.setDuration(0);
                orderInfo.setTotalAmount(new BigDecimal(0));
                orderInfo.setDeductAmount(new BigDecimal(0));
                orderInfo.setRealAmount(new BigDecimal(0));
            }
        }

        List<OrderBill> orderBillList = orderBillMapper.selectList(new LambdaQueryWrapper<OrderBill>().eq(OrderBill::getOrderId, id));
        orderInfo.setOrderBillList(orderBillList);

        R<UserInfo> userInfoResult = remoteUserInfoService.getInfo(orderInfo.getUserId());
        if (StringUtils.isNull(userInfoResult) || StringUtils.isNull(userInfoResult.getData())) {
            throw new ServiceException("获取用户信息失败");
        }
        if (R.FAIL == userInfoResult.getCode()) {
            throw new ServiceException(userInfoResult.getMsg());
        }
        UserInfoVo userInfoVo = new UserInfoVo();
        BeanUtils.copyProperties(userInfoResult.getData(), userInfoVo);
        orderInfo.setUserInfoVo(userInfoVo);
        return orderInfo;
    }

    @Override
    public OrderInfo getByOrderNo(String orderNo) {
        return orderInfoMapper.selectOne(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderNo, orderNo));
    }

    @Override
    public void processPaySucess(String orderNo) {
        //获取订单信息
        OrderInfo orderInfo = orderInfoMapper.selectOne(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderNo, orderNo).select(OrderInfo::getId, OrderInfo::getStatus));
        //未支付
        if ("1".equals(orderInfo.getStatus())) {
            orderInfo.setStatus("2");
            orderInfo.setPayTime(new Date());
            orderInfoMapper.updateById(orderInfo);
        }
    }

    @Override
    public Map<String, Object> getOrderCount(String sql) {
        // 调用mapper执行sql查询
        List<Map<String, Object>> list = baseMapper.getOrderCount(sql);

        Map dataMap = new HashMap<>();

        List<Object> monthList = new ArrayList<>();
        List<Object> orderCountList = new ArrayList<>();

        for (Map<String, Object> map : list) {
            monthList.add(map.get("order_date"));
            orderCountList.add(map.get("order_count"));
        }

        dataMap.put("dateList", monthList);
        dataMap.put("countList", orderCountList);

        return dataMap;
    }

}